package ramakrishnanStudentPackageTest;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;

import ramakrishnanmoreHealthControl.PatternFoundArrayList;
import ramakrishnanmoreHealthControl.StudentJourneyProcessor;
import ramakrishnanmoreHealthControl.StudentJrnyPatternLookUp;
import ramakrishnanmoreHealthControl.ThreadStudentJourney;
import ramakrishnanmoreHealthModel.Campus.CampusLocation;
import ramakrishnanmoreHealthModel.Campus.FoodSources.*;
import ramakrishnanmoreHealthModel.Campus.LearningEnvironment.*;
import ramakrishnanmoreHealthModel.Campus.Residences.Residence1;
import ramakrishnanmoreHealthModel.Campus.Transit.*;
import ramakrishnanmoreHealthModel.Student.*;
import ramakrishnanmoreHealthModel.Student.Student.Disease;
import ramakrishnanmoreHealthView.StudentJourneyGrid;

import junit.framework.TestCase;
import ramakrishnanmoreHealthException.StringLengthException;


public class testStudentJourney extends TestCase
	{
		StudentJourney sj;
		StudentJourney sj1;
		StudentJourney sj2;
		StudentJourney sj3;
		StudentJourney sj4;
		StudentJourney sj5;
		StudentJourney sj6;
		StudentJourney sj7;
		StudentJourney sj8;
		ArrayList<StudentJourney> testArray = new ArrayList<StudentJourney>();

		public void setUp() throws Exception
			{
				    sj = new StudentJourney();
				    sj1= new StudentJourney();
				    sj2= new StudentJourney();
				    sj3= new StudentJourney();
				    sj4 = new StudentJourney();
				    sj6 = new StudentJourney();
				    sj7 = new StudentJourney();
				    sj8 = new StudentJourney();
				    
				    //The assignment required Test case.
					sj.setStudentVisitedPlaces(new Halls(0,0,"HallTest1",701));
					sj.setStudentVisitedPlaces(new FastFood(0,1,"FastFoodTest2",702));
					sj.setStudentVisitedPlaces(new Restaurant(0,2,"RestaurantTest1",703));
					sj.setStudentVisitedPlaces(new Residence1(0,3,"ResidenceTest2",704));
					sj.setStudentVisitedPlaces(new Sidewalk(0,4,705));
					sj.setStudentVisitedPlaces(new Library(4,1,"LibTest2",706));
					sj.setStudentVisitedPlaces(new ClassRoom(4,2,"ClassRoomTest1",707));
					sj.setStudentVisitedPlaces(new Halls(4,3,"HallTest2",708));
					sj.setStudentVisitedPlaces(new Sidewalk(4,4,709));
					sj.setStudentVisitedPlaces(new Sidewalk(3,3,710));
					sj.setStudentVisitedPlaces(new Halls(2,2,"HallTest1",711));
					
					//Normal cases
					sj1.setStudentVisitedPlaces(new Halls(0,1,"Hall1",710));
					sj1.setStudentVisitedPlaces(new FastFood(0,2,"Fast2",711));
					sj1.setStudentVisitedPlaces(new Sidewalk(0,3,712));
					
					//Extreme Case
					sj1.setStudentVisitedPlaces(new Halls(0, -1, "123",-999));

					
				    //The assignment required Test case for Mapping on the Grid.
					sj7.setStudentVisitedPlaces(new Halls(0,0,"HallTest1",701));
					sj7.setStudentVisitedPlaces(new Halls(0,1,"FastFoodTest2",702));
					sj7.setStudentVisitedPlaces(new Halls(0,2,"RestaurantTest1",703));
					sj7.setStudentVisitedPlaces(new ClassRoom(0,3,"ResidenceTest2",704));
					sj7.setStudentVisitedPlaces(new Halls(0,4,"HallTes3",705));
					sj7.setStudentVisitedPlaces(new Sidewalk(1,4,706));
					sj7.setStudentVisitedPlaces(new Sidewalk(2,4,707));
					sj7.setStudentVisitedPlaces(new Sidewalk(3,4,708));
					sj7.setStudentVisitedPlaces(new Restaurant(4,4,"Rest1",709));
					sj7.setStudentVisitedPlaces(new Sidewalk(3,3,710));
					sj7.setStudentVisitedPlaces(new Residence1(2,2,"HallTest1",711));
					
					
					sj8.setStudentVisitedPlaces(new Residence1(1, 2, "res2", 701));
					sj8.setStudentVisitedPlaces(new ClassRoom(1, 3, "classRoomAddress", 702));
					sj8.setStudentVisitedPlaces(new Sidewalk(2, 4, 703));
					sj8.setStudentVisitedPlaces(new Sidewalk(3, 4, 704));
					sj8.setStudentVisitedPlaces(new Sidewalk(3, 3, 705));
					sj8.setStudentVisitedPlaces(new ClassRoom(2, 3, "classRoomAddress", 706));
			}
		
		public void testgetPatternLookupFile(){
			StudentJrnyPatternLookUp sjlp = new StudentJrnyPatternLookUp();

		}
		
		public void testTotalDistanceCalculator()
			{
				System.out.println("In testTotalDistanceCalculator");
				//Normal case
				System.out.println("Normal Case");
				assertEquals(2.17,sj.TotalDistanceCalculator(sj.getStudentVisitedPlaces()));
				
				//Corner Case
				System.out.println("Corner Case");
				assertEquals(0.4,sj1.TotalDistanceCalculator(sj1.getStudentVisitedPlaces()));


			}

		public void testsetStudentInfo()
			{
			System.out.println("In testsetStudentInfo");
			
				//Normal Case
				//Student Info is set.
				System.out.println("Normal Case");
				Student s1= new Student("Aloke", 24, 4, 160, Disease.other);
				sj.setStudentInfo(s1);
				assertEquals(s1,sj.currentStudentx_);
				assertSame(s1,sj.currentStudentx_);
				assertEquals(false, sj.currentStudentx_.getstudentInfoStatus());
				
				//Corner Case
				//The Student Information is not set. 
				System.out.println("Corner Case");
				Student s2=null;
				sj1.setStudentInfo(s2);
				assertNull(sj1.currentStudentx_);
				
				//Random Case
				System.out.println("Random Case");
				Student s3= new Student (null, -9,-9,-6,Disease.heartTrouble);
				sj3.setStudentInfo(s3);
				assertNotNull(sj3);
				assertEquals(true, sj3.currentStudentx_.getstudentInfoStatus());
			}

		
		public void testsetStudentVisitedPlaces()
			{	
			System.out.println("In testsetStudentVisitedPlaces");
				//Random
			System.out.println("Random Case");
				sj6.setStudentVisitedPlaces(null);
				assertEquals(true, sj6.getStudentVisitedPlaces().isEmpty());
			}
		
		public void testgetStudentVisitedPlaces()
			{
				//Normal Case.
				assertEquals(false, sj.getStudentVisitedPlaces().isEmpty());
				assertEquals(11, sj.getStudentVisitedPlaces().size());
				
				//Random Case: There is not information about the Student's journey
				assertTrue(sj2.getStudentVisitedPlaces().isEmpty());

			}
		
		
		public void testStudentJourneyProcessor(){
			HashMap<String, Object> testDataPairs = new HashMap<String, Object>();
			
			//Normal cases.
			testDataPairs.put("firstName", "Aloke");
			testDataPairs.put("lastName", "Ram");
			testDataPairs.put("dobmonth", "Jan");
			testDataPairs.put("dobyear", "1985");
			testDataPairs.put("height", "7");
			testDataPairs.put("weight", "80");
			testDataPairs.put("disease", Disease.heartTrouble);
			
			StudentJourneyProcessor sjp = new StudentJourneyProcessor(testDataPairs);
			sjp.configureStudentObject();
			assertEquals(true, sjp.getSuccessStatus());
			
			
			//Corner Cases
			HashMap<String, Object> testIllegalDataPairs = new HashMap<String, Object>();
			testIllegalDataPairs.put("firstName", "ssssssssssssssssss");
			testIllegalDataPairs.put("lastName", "ssssssssssssssssss");
			testIllegalDataPairs.put("age", "ssssssssssssssssss");
			testIllegalDataPairs.put("height", "ssssssssssssssssss");
			testIllegalDataPairs.put("weight", "ssssssssssssssssss");
			testIllegalDataPairs.put("disease", Disease.heartTrouble);
			StudentJourneyProcessor sjp2 = new StudentJourneyProcessor(testIllegalDataPairs);
			
			sjp2.configureStudentObject();
			assertEquals(false, sjp2.getSuccessStatus());
			
		}

		
		//This is it.
		public void testStudentJourneyGrid () throws IOException
			{
			System.out.println("In testStudentJourneyGrid");
				//Normal Case
			System.out.println("Normal Case");
				ArrayList<CampusLocation> studentJourneyInfo1 = sj7.getStudentVisitedPlaces();
				
				
				StudentJourneyGrid sjg1 = new StudentJourneyGrid(studentJourneyInfo1, "Testing for Student1");
				assertEquals(true, sjg1.getgridDisplaySuccess());
				
				//Corner Case
				System.out.println("Corner Case");
				ArrayList<CampusLocation> studentJourneyInfo2 = sj.getStudentVisitedPlaces();
				StudentJourneyGrid sjg2 = new StudentJourneyGrid(studentJourneyInfo2, "Testing for Student 2");
				assertEquals(true, sjg2.getgridDisplaySuccess());
			
				
			}
		
		
		
		public void testStringLengthException(){
			
			//corner case.
			try{
			throw new StringLengthException(null);	
			}
			catch(StringLengthException e){
				assertEquals(null, e.getReturnDefaultValue());
			}
		}
		
		
		public void testCalculateStudentAge(){
			
			StudentJourneyProcessor sjp = new StudentJourneyProcessor();
			
			//Normal cases
			assertEquals(24, sjp.CalculateStudentAge("Jan", 1985));
			
			//Corner Cases
			assertEquals(0, sjp.CalculateStudentAge(null, 1985));
			assertEquals(0, sjp.CalculateStudentAge("January", 1985));
			
		}
		
		//Predict the students path based on a pre defined routes saved in a file and the total student journey
		public void testRecursion() throws FileNotFoundException{
			
			//This will load the content of the pattern lookup file to an array. 
			StudentJrnyPatternLookUp sji = new StudentJrnyPatternLookUp();
			StudentJrnyPatternLookUp sji1 = new StudentJrnyPatternLookUp();
			
			
			//This will find the pattern for each pair of student location starting from the end.
			ArrayList<PatternFoundArrayList> myTotalPeridiction = sji.PatternEngine(sj7.getStudentVisitedPlaces());
			ArrayList<PatternFoundArrayList> myTotalPrediction1 = sji1.PatternEngine(sj8.getStudentVisitedPlaces());
			
			for (int i= 0 ; i<myTotalPeridiction.size(); i++){
				String preditcionForLocation = "[ " +myTotalPeridiction.get(i).getLoc1() + " " + myTotalPeridiction.get(i).getLoc2() + " ]";
				System.out.print("Total prediction for "+ preditcionForLocation + " is: " + myTotalPeridiction.get(i).getFormattedStringList() +"\n");
			}	
			
			System.out.print("\n\n Starting Assignemen4 Argument\n");
			for(int j = 0; j<myTotalPrediction1.size(); j++){
				String preditcionForLocation1 = "[ " +myTotalPrediction1.get(j).getLoc1() + " " + myTotalPrediction1.get(j).getLoc2() + " ]";
				String myTotalPrediction = myTotalPrediction1.get(j).getFormattedStringList(); 
				System.out.print("Total prediction for assignement4: "+ preditcionForLocation1 + " is: " + myTotalPrediction +"\n");
			
				switch (j)
				{
				
				//test cases: 
				case 0:
					assertEquals("23 24 34 44 33 22 21 31 32 33 ", myTotalPrediction);
					break;
				case 1:
					assertEquals("33 34 ", myTotalPrediction);
					break;
				case 2:
					assertEquals("34 44 33 23 24 34 44 33 22 21 31 32 33 ", myTotalPrediction);
					break;
				case 3:
					assertEquals("24 13 ", myTotalPrediction);
					break;
				case 4:
					assertEquals("13 12 ", myTotalPrediction);
					break;
				}
			}
		
		}

		
		public void testLocationPatternMatcher(){
			StudentJrnyPatternLookUp sjl1 = new StudentJrnyPatternLookUp();
			try {
				sjl1.getPatternLookupFileArrayList();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			PatternFoundArrayList myTotPattern1 = sjl1.LocationPatternMatcher("00", "01");
			assertEquals(31, myTotPattern1.getListString().size());
			
			PatternFoundArrayList myTotPattern2 = sjl1.LocationPatternMatcher("01", "02");
			assertEquals(28, myTotPattern2.getListString().size());
		}
		
		public void testURLTextFile() throws IOException{
			URL urlTravelTextFile = new URL(
			"http://csmet.bu.edu/ebraude/565/StudentSimSource.txt");
			
			
			//Internet connection should be avaliable.
			assertNotNull(urlTravelTextFile.getHost());
			
			InputStream studentTravelInfo = urlTravelTextFile.openStream();
			String studentNameAtLocation = null;
			int timeSpentAtLocation = 0;
			BufferedReader getStudentFromURL = new BufferedReader(
					new InputStreamReader(studentTravelInfo));
			String currentLine = null;
			while (((currentLine = getStudentFromURL.readLine()) != null)) {
				String[] uRLText = ThreadStudentJourney.parseFileTextToArray(currentLine);
				
				
				//The format of the file should be 500 Edward Jones 3 3
				assertEquals(5, uRLText.length);
							
				
			}
			
			
		}
		
		public void tearDown() throws Exception
			{
			}

	}
